import hashlib
from itertools import groupby
from pathlib import Path

dir_list = [
    r'F:\z\Telegram\mp4',
    r'F:\z\Telegram\mov',
    r'F:\z\Twitter',
    r'F:\z\视频'
]


def get_file_hash(file_path):
    """计算文件的MD5哈希值，增加文件存在性检查"""
    if not Path(file_path).exists():
        print(f"警告：文件 {file_path} 不存在，将被跳过。")
        return None

    hash_md5 = hashlib.md5()
    with open(file_path, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()


path_list = []
size_dict = {}
for cu_dir in dir_list:
    for path in Path(cu_dir).rglob('*'):
        if path.is_file():
            path_list.append(path)
            size_dict[path] = path.stat().st_size

print(f"总共找到 {len(path_list)} 个文件")
# 对比size_dict中的信息是否有value重复的项，如果有，则将重复的项分组打印出来
for size, paths in ((size, list(paths)) for size, paths in
                    groupby(sorted(size_dict.items(), key=lambda item: item[1]), lambda item: item[1])):
    if len(paths) > 1:  # 只处理有重复的文件大小
        for path in paths:
            # 对每组大小相同的文件，进一步按哈希值分组
            hash_groups = {}
            for path_obj, _ in paths: # 遍历路径列表中的每一项，其中paths是一个包含路径对象和相关信息的元组列表
                file_hash = get_file_hash(str(path_obj))
                # 如果字典中不存在当前哈希值的键，则初始化一个空列表，并将当前路径对象添加到列表中
                # 如果已存在，则直接将当前路径对象添加到对应的列表中
                # 这里使用setdefault方法来确保每个哈希值只被初始化一次
                hash_groups.setdefault(file_hash, []).append(path_obj)

            # 打印哈希值相同（即内容也相同）的文件组
            for hash_val, files in hash_groups.items():
                if len(files) > 1:  # 确保是重复的（基于哈希）
                    print(f"文件大小为 {size} 字节，且哈希值为 {hash_val} 的重复文件有：")
                    for file_path in files:
                        print(f"\t{file_path}")
                    # 每组重复文件仅保留第一个文件

